<template>
  <div class="roleList">
    <!-- 面包屑 -->
    <el-breadcrumb separator-class="el-icon-caret-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 添加按钮 -->
    <el-button type="success" @click="showAddDialog">添加角色</el-button>
    <!-- 表格 -->
    <el-table :data="roleList" border style="width: 100%;margin-top:15px">
      <el-table-column type="expand">
        <template slot-scope="scope">
          <el-row
            v-for="first in scope.row.children"
            :key="first.id"
            style="margin-bottom:15px;border-bottom:1px solid aqua;"
          >
            <el-col :span="4">
              <el-tag
                closable
                :type="'success'"
                @close="cnt=0;delRight(scope.row,first.id)"
              >{{first.authName}}</el-tag>
            </el-col>
            <el-col :span="20">
              <el-row v-for="second in first.children" :key="second.id" style="margin-bottom:10px;">
                <el-col :span="4">
                  <el-tag
                    closable
                    :type="'info'"
                    @close="cnt=0;delRight(scope.row,second.id)"
                  >{{second.authName}}</el-tag>
                </el-col>
                <el-col :span="20">
                  <el-tag
                    closable
                    :type="'error'"
                    v-for="third in second.children"
                    :key="third.id"
                    style="margin-right:5px;margin-bottom:5px"
                    @close="cnt=0;delRight(scope.row,third.id)"
                  >{{third.authName}}</el-tag>
                </el-col>
              </el-row>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24" v-show="scope.row.children.length===0">无任何权限,先分配!</el-col>
          </el-row>
        </template>
      </el-table-column>
      <el-table-column type="index" width="50"></el-table-column>
      <el-table-column label="角色名称" prop="roleName"></el-table-column>
      <el-table-column label="描述" prop="roleDesc"></el-table-column>
      <el-table-column label="操作" width="400">
        <template slot-scope="scope">
          <el-tooltip class="item" effect="dark" content="编辑" placement="top">
            <el-button type="primary" icon="el-icon-edit"></el-button>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="角色授权" placement="top">
            <el-button type="success" icon="el-icon-share" @click="showGrantDialog(scope.row)"></el-button>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="删除" placement="top">
            <el-button type="warning" icon="el-icon-delete"></el-button>
          </el-tooltip>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分配权限对话框 -->
    <el-dialog title="权限分配" :visible.sync="grantdialogTableVisible">
      <el-tree
        :data="rightList"
        ref="tree"
        show-checkbox
        node-key="id"
        :default-expanded-all="true"
        :default-checked-keys="chkedArr"
        :props="defaultProps"
      ></el-tree>
      <div slot="footer" class="dialog-footer">
        <el-button @click="grantdialogTableVisible=false">取 消</el-button>
        <el-button type="primary" @click="grantRole">确 定</el-button>
      </div>
    </el-dialog>
    <!-- 添加角色对话框 -->
    <el-dialog title="添加角色" :visible.sync="adddialogFormVisible">
      <el-form :model="addForm" :label-width="'80px'">
        <el-form-item label="角色名称">
          <el-input v-model="addForm.roleName" auto-complete="off"></el-input>
        </el-form-item>
        <el-form-item label="角色描述">
          <el-input v-model="addForm.roleDesc" auto-complete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="adddialogFormVisible=false">取 消</el-button>
        <el-button type="primary" @click="addRole">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import {
  getAllRoleList,
  delRightByRoleId,
  grantRoleById,
  addRole
} from '@/api/role_index.js'
import { getAllRightList } from '@/api/right_index.js'
export default {
  data () {
    return {
      addForm: {
        roleName: '',
        roleDesc: ''
      },
      adddialogFormVisible: false,
      roleId: '',
      cnt: 0,
      defaultProps: {
        label: 'authName',
        children: 'children'
      },
      grantdialogTableVisible: false,
      roleList: [],
      rightList: [],
      // 当前角色拥有的权限id
      chkedArr: []
    }
  },
  methods: {
    // 添加角色
    async addRole () {
      // try:只能捕获主线程中的异常,尝试进行执行的代码块
      try {
        let res = await addRole(this.addForm)
        console.log(res)
        if (res.data.meta.status === 201) {
          this.$message.success(res.data.meta.msg)
          this.adddialogFormVisible = false
          this.init()
        } else {
          this.$message.error(res.data.meta.msg)
        }
      } catch (exp) {
        // 如果有错,就让catch模块进行处理
        this.$message.error('服务器异常')
      } finally {
        // 无论操作是否有错都会执行的代码块
      }
    },
    // 打开添加角色对话框
    showAddDialog () {
      this.adddialogFormVisible = true
    },
    // async:标记这个函数中有异步操作
    // 实现角色授权
    async grantRole () {
      // 先获取到当前用户所选择所有的权限id,拼接为以,分隔的字符串
      // var rids=''
      // getCheckedKeys
      // getCheckedNodes
      // console.log(this.$refs.tree.getCheckedKeys())
      // 获取父级节点
      // console.log(this.$refs.tree.getHalfCheckedKeys())
      // console.log(this.$refs.tree.getHalfCheckedNodes())
      // 1.我们有:[{id:109,pid:'107,102'},{id:154,pid:'107,102'}]
      let arr = this.$refs.tree.getCheckedNodes()
      // 2.遍历数组,进行数据拼接
      let temp = []
      for (let i = 0; i < arr.length; i++) {
        temp.push(arr[i].id + ',' + arr[i].pid)
      }
      // 3.拼接数组元素再转换为数组
      temp = temp.join(',').split(',')
      // console.log(temp)
      // 4.只有数组能去重, new Set(数组)可以去除数组中的重复数据,返回值是一个set对象
      temp = [...new Set(temp)]
      // 此处我们需要的是:'102,107,109,154'
      // await:此关键字是标记后面的是异步操作,要等待这个异步操作执行完毕才进行下一步行为
      // await必须写在async中,且asyne只能加给上一级函数
      let res = await grantRoleById(this.roleId, temp.join(','))
      console.log(res)
      if (res.data.meta.status === 200) {
        this.$message.success(res.data.meta.msg)
        this.grantdialogTableVisible = false
        this.init()
      } else {
        this.$message.error(res.data.meta.msg)
      }
    },
    // 弹出角色授权对话框
    showGrantDialog (row) {
      // 此处进行数据的存储是为了后期角色授权时能正确获取角色id
      this.roleId = row.id
      // 1.让对话框显示
      // 2.加载树形组件的数据
      // 3.获取权限id,让节点默认被选中
      this.grantdialogTableVisible = true
      // 加载树形组件的数据
      // getAllRightList('tree').then(res => {
      //   console.log(res)
      //   this.rightList = res.data.data
      // })
      // 深拷贝
      this.rightList = [...this.rightList]
      this.chkedArr.length = 0
      // 获取当前角色的所有权限id,添加到chkedArr
      // 只要获取最后一级,做个判断
      row.children.forEach(first => {
        if (first.children.length > 0) {
          first.children.forEach(second => {
            if (second.children.length > 0) {
              second.children.forEach(third => {
                this.chkedArr.push(third.id)
              })
            }
          })
        }
      })
    },
    delRight (row, rightId) {
      console.log(row.id, rightId)
      delRightByRoleId(row.id, rightId)
        .then(res => {
          if (this.cnt === 0) {
            this.$message.success('角色权限删除成功')
            this.cnt++
          }
          // 刷新不要使用init,init会刷新整个页面,造成展开合并
          // res.data.data就是实现当前权限删除操作后该角色还有的权限数据
          // 为避免刷新整个表格,可以将这个数据重置当前角色的展开行数据
          // 展开行数据: scope.row.children
          row.children = res.data.data
          // 判断当前权限是有还有下一级权限,如果没有,则需要将这一级权限也删除
          row.children.forEach((v1, in1) => {
            // 遍历一级权限
            if (v1.children.length === 0) {
              // 说明此一级权限下无二级权限
              this.delRight(row, v1.id)
            } else {
              v1.children.forEach((v2, in2) => {
                if (v2.children.length === 0) {
                  // 说明此二级权限下无三级权限
                  this.delRight(row, v2.id)
                }
              })
            }
          })
        })
        .catch(err => {
          console.log(err)
        })
    },
    init () {
      // 角色列表
      getAllRoleList().then(res => {
        console.log(res)
        if (res.data.meta.status === 200) {
          this.roleList = res.data.data
        }
      })
    }
  },
  mounted () {
    this.init()
    getAllRightList('tree').then(res => {
      console.log(res)
      this.rightList = res.data.data
    })
  }
}
</script>
<style lang="less">
</style>
